package org.wu.spring.db.integration.compare.infrastructure.persistence.mysql;

import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.wu.framework.lazy.orm.core.config.DefaultLazyOperationAttribute;
import org.wu.framework.lazy.orm.core.config.LazyOperationAttribute;
import org.wu.framework.lazy.orm.core.config.enums.LazyDataSourceType;
import org.wu.framework.lazy.orm.core.config.prop.DefaultLazyDataSourceAttribute;
import org.wu.framework.lazy.orm.core.config.prop.LazyDataSourceAttribute;
import org.wu.framework.lazy.orm.core.persistence.conf.LazyColumn;
import org.wu.framework.lazy.orm.core.persistence.conf.LazyTableEndpoint;
import org.wu.framework.lazy.orm.core.source.adapter.SourceFactory;
import org.wu.framework.lazy.orm.database.lambda.domain.LazyPage;
import org.wu.framework.lazy.orm.database.lambda.dynamic.function.DynamicDatasourceSupport;
import org.wu.framework.lazy.orm.database.lambda.stream.lambda.LazyLambdaStream;
import org.wu.framework.lazy.orm.database.sql.expand.database.persistence.factory.LazyLambdaStreamFactory;
import org.wu.framework.web.response.Result;
import org.wu.framework.web.response.ResultFactory;
import org.wu.spring.db.integration.compare.config.DbConfig;
import org.wu.spring.db.integration.compare.domain.model.sys.user.DbComparisonRepository;
import org.wu.spring.db.integration.compare.domain.model.sys.user.SysUser;
import org.wu.spring.db.integration.compare.enums.DatabaseType;
import org.wu.spring.db.integration.compare.enums.ExecuteType;
import org.wu.spring.db.integration.compare.infrastructure.persistence.DbComparisonRepositoryAbstract;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;


@Slf4j
//@Component
public class LazyMySqlComparisonRepository extends DbComparisonRepositoryAbstract implements DbComparisonRepository {


    private final DbConfig dbConfig;
    private final LazyLambdaStream lazyLambdaStream;
    private final String DATABASE_ID = "mysql";

    public LazyMySqlComparisonRepository(DbConfig dbConfig) {
        this.dbConfig = dbConfig;
        DbConfig.MysqlConfig mysqlConfig = dbConfig.getMysqlConfig();
        String url = mysqlConfig.getUrl();
        String username = mysqlConfig.getUsername();
        String password = mysqlConfig.getPassword();
        LazyDataSourceAttribute lazyDataSourceAttribute = new DefaultLazyDataSourceAttribute();
        lazyDataSourceAttribute.setUrl(url);
        lazyDataSourceAttribute.setUsername(username);
        lazyDataSourceAttribute.setPassword(password);
        lazyDataSourceAttribute.setAlias(DATABASE_ID);
        DefaultLazyOperationAttribute defaultLazyOperationAttribute = new DefaultLazyOperationAttribute(

        );
        defaultLazyOperationAttribute.setPrintfQuery(false);

        this.lazyLambdaStream = LazyLambdaStreamFactory.
                createLazyLambdaStream(lazyDataSourceAttribute,defaultLazyOperationAttribute);
    }

    /**
     * describe 批量新增
     *
     * @param rowSize    @return {@link Result <  List  < SysUser >>} 新增后领域对象集合
     * @param columnSize
     * @author Jia wei Wu
     * @date 2024/02/28 11:27 上午
     **/
    @Override
    protected Result<List<SysUser>> doBatchStory(int rowSize, int columnSize) throws Exception {
        String schemaName = dbConfig.getSchemaName();
        String tableName = dbConfig.getTableName();

        AtomicReference<LocalDateTime> startTime = new AtomicReference<>(LocalDateTime.now());
        AtomicBoolean success = new AtomicBoolean(true);

        DynamicDatasourceSupport.doOtherSilently(LazyDataSourceType.MySQL,DATABASE_ID, schemaName, () -> {

            // 创建数据库
            lazyLambdaStream.executeSQLForBean("create database if not exists {0};", Boolean.class, schemaName);
            // 删除表
            lazyLambdaStream.executeSQLForBean("drop table if exists {0}.{1}", Integer.class, schemaName, tableName);

            // 创建表
            Map<String, Object> rowData = getRowData(columnSize);

            LazyTableEndpoint<?> lazyTableEndpoint = SourceFactory
                    .analyzeLazyTableFromMap(LazyDataSourceType.MySQL, schemaName, tableName, rowData);
            lazyLambdaStream.updateTable(lazyTableEndpoint);

            success.set(true);
            startTime.set(LocalDateTime.now());
            try {

                List<Map<String, Object>> weakInsertList=new ArrayList<>();
                for (int i = 0; i < rowSize; i++) {
                    rowData = getRowData(columnSize);
                    weakInsertList.add(rowData);
                }
                int groupSize=(columnSize*rowSize)/10000;
                lazyLambdaStream.weakInsertMultiple(schemaName, tableName, weakInsertList,1000);
            } catch (Exception e) {
                e.printStackTrace();
                success.set(false);
            }
        });

        LocalDateTime endTime = LocalDateTime.now();
        storyRecord(DatabaseType.MYSQL, ExecuteType.batchStory, startTime.get(), endTime, rowSize, columnSize, success.get());

        return ResultFactory.successOf();
    }

    /**
     * describe 分页查询多个
     *
     * @param rowSize    当前页数
     * @param columnSize
     * @return {@link Result<   LazyPage   <SysUser>>} 分页领域对象
     * @author Jia wei Wu
     * @date 2024/02/28 11:27 上午
     **/
    @Override
    protected Result<LazyPage<SysUser>> doFindPage(int rowSize, int columnSize) throws Exception {
        String schemaName = dbConfig.getSchemaName();
        String tableName = dbConfig.getTableName();

        AtomicBoolean success = new AtomicBoolean(true);
        AtomicReference<LocalDateTime> startTime = new AtomicReference<>(LocalDateTime.now());

        DynamicDatasourceSupport.doOtherSilently(LazyDataSourceType.MySQL,DATABASE_ID, schemaName, () -> {
            // 查询表字段
            String tableColumnListSql = SourceFactory.findTableColumnListSql(LazyDataSourceType.MySQL, schemaName, tableName);
            Class<? extends LazyColumn> columnInfoClass = SourceFactory.findColumnInfoClass(LazyDataSourceType.MySQL);
            List<? extends LazyColumn> lazyColumns = lazyLambdaStream.executeSQL(tableColumnListSql, columnInfoClass);
            String queryColumn = lazyColumns.subList(0, (Math.min(columnSize, lazyColumns.size()))).stream().map(LazyColumn::getColumnName).collect(Collectors.joining(","));

            startTime.set(LocalDateTime.now());
            try {
                // 过滤指定条数
                List<HashMap> objects = lazyLambdaStream.executeSQL("select {0} from {1}.{2} limit {3}", HashMap.class,
                        queryColumn,
                        schemaName,
                        tableName,
                        rowSize
                );
                log.info("find success rowSize {},columnSize:{}",objects.size(),objects.get(0).size());
            } catch (Exception e) {
                e.printStackTrace();
                success.set(false);
            }
        });

        LocalDateTime endTime = LocalDateTime.now();
        storyRecord(DatabaseType.MYSQL, ExecuteType.findPage, startTime.get(), endTime, rowSize,columnSize , success.get());


        return ResultFactory.successOf();
    }
}
